import React, { useState, useEffect, useRef } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import {
  Box,
  Typography,
  Paper,
  Button,
  Alert,
  CircularProgress,
  Select,
  MenuItem,
  FormControl,
  InputLabel,
  Chip,
} from '@mui/material';
import {
  ArrowBack as BackIcon,
  Computer as ConsoleIcon,
  Refresh as RefreshIcon,
} from '@mui/icons-material';
import { useConnectionStore } from '../../stores/connectionStore';
import { useDomainStore } from '../../stores/domainStore';
import { useConsoleWebSocket } from '../../services/console';

// 添加xterm.js的导入
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import 'xterm/css/xterm.css';

const DomainConsole: React.FC = () => {
  const { name } = useParams<{ name: string }>();
  const navigate = useNavigate();
  const currentConnection = useConnectionStore(state => state.currentConnection);
  const { currentDomain, getDomainDetail, loading, error, clearError } = useDomainStore();
  
  // const [tabValue, setTabValue] = useState(0); // 暂时未使用，保留供将来使用
  const [consoleType, setConsoleType] = useState<'vnc' | 'spice' | 'serial'>('vnc');
  const [consoleInfo, setConsoleInfo] = useState<any>(null);
  const [consoleLoading, setConsoleLoading] = useState(false);
  // 添加终端相关状态
  const [isTerminalConnected, setIsTerminalConnected] = useState(false);
  const terminalRef = useRef<HTMLDivElement>(null);
  const terminalInstance = useRef<Terminal | null>(null);
  
  // 使用WebSocket客户端Hook
  const { 
    connect: connectWebSocket, 
    disconnect: disconnectWebSocket, 
    send: sendWebSocketData,
    isConnected: isWebSocketConnected,
    isConnecting: isWebSocketConnecting
  } = useConsoleWebSocket({
    onOpen: () => {
      setIsTerminalConnected(true);
      terminalInstance.current?.write('\x1b[32mConnected to serial console\x1b[0m\r\n');
    },
    onClose: () => {
      setIsTerminalConnected(false);
      terminalInstance.current?.write('\x1b[31mSerial console connection closed\x1b[0m\r\n');
    },
    onError: (error) => {
      console.error('Serial console WebSocket error:', error);
      terminalInstance.current?.write('\x1b[31mError connecting to serial console\x1b[0m\r\n');
      setIsTerminalConnected(false);
    },
    onMessage: (data) => {
      if (terminalInstance.current) {
        // 处理接收到的数据并在终端中显示
        if (typeof data === 'string') {
          terminalInstance.current.write(data);
        } else {
          // 处理二进制数据
          const text = new TextDecoder().decode(data);
          terminalInstance.current.write(text);
        }
      }
    }
  });

  // 获取虚拟机详情
  useEffect(() => {
    if (currentConnection && name) {
      getDomainDetail(currentConnection, name);
    }
  }, [currentConnection, name, getDomainDetail]);

  // 清除错误
  useEffect(() => {
    if (error) {
      const timer = setTimeout(() => clearError(), 5000);
      return () => clearTimeout(timer);
    }
  }, [error, clearError]);

  // 初始化终端
  useEffect(() => {
    // 当切换到serial控制台时初始化终端
    if (consoleType === 'serial' && terminalRef.current) {
      // 如果已经有终端实例，先清理
      if (terminalInstance.current) {
        terminalInstance.current.dispose();
        terminalInstance.current = null;
      }
      
      const term = new Terminal({
        cursorBlink: true,
        theme: {
          background: '#000000',
          foreground: '#ffffff'
        },
        rows: 30,
        cols: 80
      });
      
      const fitAddon = new FitAddon();
      term.loadAddon(fitAddon);
      
      term.open(terminalRef.current);
      fitAddon.fit();
      
      terminalInstance.current = term;
      
      // 添加终端输入处理
      term.onData((data: string) => {
        if (isWebSocketConnected) {
          sendWebSocketData(data);
        }
      });
    }
    
    // 当切换到其他控制台类型时，清理serial控制台连接
    if (consoleType !== 'serial') {
      disconnectWebSocket();
      setIsTerminalConnected(false);
    }
    
    // 清理函数
    return () => {
      disconnectWebSocket();
      if (terminalInstance.current) {
        terminalInstance.current.dispose();
        terminalInstance.current = null;
      }
      setIsTerminalConnected(false);
    };
  }, [consoleType, isWebSocketConnected, sendWebSocketData, disconnectWebSocket]); // 依赖consoleType，当它改变时重新运行

  // 获取控制台信息
  const fetchConsoleInfo = async () => {
    if (!currentConnection || !name) return;
    
    setConsoleLoading(true);
    try {
      // 从API获取真实的控制台信息
      const response = await fetch(`http://localhost:8080/api/v1/console/info?connection=${currentConnection}&name=${name}`);
      const data = await response.json();
      
      if (data && data.consoles) {
        setConsoleInfo(data.consoles[consoleType]);
        
        // 如果是serial控制台，自动连接
        if (consoleType === 'serial' && data.consoles[consoleType]) {
          // 延迟一点时间确保终端已经初始化
          setTimeout(() => {
            connectToSerialConsole();
          }, 100);
        }
      } else {
        throw new Error('未能获取有效的控制台信息');
      }
    } catch (error) {
      console.error('获取控制台信息失败:', error);
    } finally {
      setConsoleLoading(false);
    }
  };

  // 连接控制台
  const connectConsole = () => {
    if (!consoleInfo) return;
    
    // 对于serial控制台，我们使用term.js
    if (consoleType === 'serial') {
      connectToSerialConsole();
      return;
    }
    
    // 根据API返回的ws_path构建完整的WebSocket URL
    let websocketUrl = '';
    if (consoleInfo.ws_path) {
      const baseUrl = window.location.origin;
      websocketUrl = baseUrl.replace(/^http/, 'ws') + consoleInfo.ws_path;
    }
    
    const { proxy_url } = consoleInfo;
    
    switch (consoleType) {
      case 'vnc':
        if (websocketUrl) {
          // 使用WebSocket连接VNC
          window.open(websocketUrl, '_blank', 'width=800,height=600');
        } else if (proxy_url) {
          // 构建VNC连接URL
          const vncUrl = `vnc://${proxy_url}`;
          window.open(vncUrl, '_blank');
        }
        break;
      case 'spice':
        if (websocketUrl) {
          // 使用WebSocket连接SPICE
          window.open(websocketUrl, '_blank', 'width=800,height=600');
        }
        break;
    }
  };

  // 连接到serial控制台WebSocket
  const connectToSerialConsole = () => {
    if (!consoleInfo || !consoleInfo.ws_path || !terminalInstance.current) {
      console.error('Missing console info or terminal instance');
      return;
    }
    
    try {
      const baseUrl = window.location.origin;
      const websocketUrl = baseUrl.replace(/^http/, 'ws') + consoleInfo.ws_path;
      
      console.log('Connecting to serial console:', websocketUrl);
      connectWebSocket(websocketUrl);
    } catch (error) {
      console.error('Failed to connect to serial console:', error);
      terminalInstance.current?.write('\x1b[31mFailed to connect to serial console\x1b[0m\r\n');
    }
  };

  if (!currentConnection) {
    return (
      <Box>
        <Typography variant="h4" component="h1" gutterBottom fontWeight="bold">
          虚拟机控制台
        </Typography>
        <Alert severity="warning">
          请先选择一个连接
        </Alert>
      </Box>
    );
  }

  if (loading && !currentDomain) {
    return (
      <Box display="flex" justifyContent="center" alignItems="center" minHeight="400px">
        <CircularProgress />
      </Box>
    );
  }

  if (!currentDomain) {
    return (
      <Box>
        <Typography variant="h4" component="h1" gutterBottom fontWeight="bold">
          虚拟机控制台
        </Typography>
        <Alert severity="error">
          未找到虚拟机 "{name}"
        </Alert>
      </Box>
    );
  }

  if (currentDomain.state !== 'running') {
    return (
      <Box>
        <Box display="flex" alignItems="center" mb={3}>
          <Button onClick={() => navigate('/domains')} sx={{ mr: 1, minWidth: 'auto' }}>
            <BackIcon />
          </Button>
          <Typography variant="h4" component="h1" fontWeight="bold">
            虚拟机控制台: {currentDomain.name}
          </Typography>
        </Box>

        <Alert severity="warning">
          虚拟机当前状态为 "{currentDomain.state}"，无法访问控制台。请先启动虚拟机。
        </Alert>
      </Box>
    );
  }

  return (
    <Box>
      <Box display="flex" alignItems="center" mb={3}>
        <Button onClick={() => navigate('/domains')} sx={{ mr: 1, minWidth: 'auto' }}>
          <BackIcon />
        </Button>
        <Typography variant="h4" component="h1" fontWeight="bold">
          虚拟机控制台: {currentDomain.name}
        </Typography>
      </Box>

      {error && (
        <Alert severity="error" sx={{ mb: 2 }} onClose={clearError}>
          {error}
        </Alert>
      )}

      <Paper sx={{ p: 3, mb: 3 }}>
        <Box display="flex" justifyContent="space-between" alignItems="center" mb={2}>
          <Typography variant="h6">
            控制台配置
          </Typography>
          <Chip 
            label={currentDomain.state === 'running' ? '运行中' : '已停止'}
            color={currentDomain.state === 'running' ? 'success' : 'default'}
            size="small"
          />
        </Box>

        <Box sx={{ display: 'flex', gap: 2, mb: 3 }}>
          <FormControl sx={{ minWidth: 200 }}>
            <InputLabel>控制台类型</InputLabel>
            <Select
              value={consoleType}
              onChange={(e) => setConsoleType(e.target.value as any)}
              label="控制台类型"
            >
              <MenuItem value="vnc">VNC图形控制台</MenuItem>
              <MenuItem value="spice">SPICE图形控制台</MenuItem>
              <MenuItem value="serial">串口控制台</MenuItem>
            </Select>
          </FormControl>
          
          <Button
            variant="outlined"
            onClick={fetchConsoleInfo}
            disabled={consoleLoading}
            startIcon={consoleLoading ? <CircularProgress size={16} /> : <RefreshIcon />}
          >
            刷新
          </Button>
        </Box>

        {/* 为serial控制台显示终端 */}
        {consoleType === 'serial' && (
          <Box sx={{ mb: 3 }}>
            <Box 
              ref={terminalRef} 
              sx={{ 
                width: '100%', 
                height: '400px',
                bgcolor: 'black',
                borderRadius: 1,
                mb: 2,
                overflow: 'hidden'
              }} 
            />
            <Button
              variant="contained"
              onClick={connectToSerialConsole}
              disabled={!consoleInfo || isTerminalConnected}
            >
              {isTerminalConnected ? '已连接' : '连接串口'}
            </Button>
          </Box>
        )}

        {consoleInfo && consoleType !== 'serial' && (
          <Box sx={{ mb: 3 }}>
            <Typography variant="subtitle2" gutterBottom>
              连接信息：
            </Typography>
            <Box sx={{ fontFamily: 'monospace', fontSize: '0.875rem', bgcolor: 'grey.50', p: 2, borderRadius: 1 }}>
              {consoleInfo.ws_path && (
                <div>WebSocket URL: {window.location.origin.replace(/^http/, 'ws') + consoleInfo.ws_path}</div>
              )}
              {consoleInfo.proxy_url && (
                <div>代理URL: {consoleInfo.proxy_url}</div>
              )}
              {consoleInfo.token && (
                <div>令牌: {consoleInfo.token}</div>
              )}
              {consoleInfo.expires_at && (
                <div>过期时间: {new Date(consoleInfo.expires_at).toLocaleString()}</div>
              )}
            </Box>
          </Box>
        )}

        <Box sx={{ display: 'flex', gap: 2 }}>
          <Button
            variant="contained"
            onClick={connectConsole}
            disabled={!consoleInfo || (consoleType === 'serial' && (isTerminalConnected || isWebSocketConnecting))}
            startIcon={<ConsoleIcon />}
          >
            {consoleType === 'serial' && isTerminalConnected ? '已连接' : 
             consoleType === 'serial' && isWebSocketConnecting ? '连接中...' : '连接控制台'}
          </Button>
          
          {consoleInfo?.ws_path && consoleType !== 'serial' && (
            <Button
              variant="outlined"
              onClick={() => {
                const baseUrl = window.location.origin;
                const websocketUrl = baseUrl.replace(/^http/, 'ws') + consoleInfo.ws_path;
                window.open(websocketUrl, '_blank', 'width=800,height=600');
              }}
              disabled={!consoleInfo}
            >
              在新窗口中打开
            </Button>
          )}
          {consoleType === 'serial' && consoleInfo && (
            <Button
              variant="outlined"
              onClick={connectToSerialConsole}
              disabled={isTerminalConnected || isWebSocketConnecting}
            >
              {isTerminalConnected ? '重新连接' : '连接'}
            </Button>
          )}
        </Box>
      </Paper>

      <Paper sx={{ p: 3 }}>
        <Typography variant="h6" gutterBottom>
          控制台说明
        </Typography>
        
        <Box sx={{ mb: 2 }}>
          <Typography variant="subtitle2" gutterBottom>
            VNC控制台：
          </Typography>
          <Typography variant="body2" color="text.secondary">
            VNC (Virtual Network Computing) 是一种图形桌面共享系统，允许您远程查看和控制虚拟机的图形界面。
          </Typography>
        </Box>

        <Box sx={{ mb: 2 }}>
          <Typography variant="subtitle2" gutterBottom>
            SPICE控制台：
          </Typography>
          <Typography variant="body2" color="text.secondary">
            SPICE (Simple Protocol for Independent Computing Environments) 是一种高性能的远程显示协议，专为虚拟环境设计。
          </Typography>
        </Box>

        <Box sx={{ mb: 2 }}>
          <Typography variant="subtitle2" gutterBottom>
            串口控制台：
          </Typography>
          <Typography variant="body2" color="text.secondary">
            串口控制台提供基于文本的界面，适用于系统调试和命令行操作。
          </Typography>
        </Box>

        <Alert severity="info" sx={{ mt: 2 }}>
          注意：某些控制台类型可能需要额外的浏览器插件或配置。WebSocket连接通常提供最佳的用户体验。
        </Alert>
      </Paper>
    </Box>
  );
};

export default DomainConsole;